<template>
  <div
    ref="wrapper"
    class="scroll-wrapper"
  >
    <slot></slot>
  </div>
</template>
  
<script lang="ts" setup>
    // vue3使用的东西你都得引入一下别忘记了
import {
  withDefaults,
  defineProps,
  defineEmits,
  ref,
  watch,
  onMounted,
  nextTick,
} from "vue";
import BScroll from "better-scroll";
// wrapper是HTML元素 默认为null
const wrapper = ref<null | HTMLDivElement>(null);
const scroll = ref();
interface scrollProps {
  probeType: number;
  click: boolean;
  scrollx: boolean;
  listenScroll: boolean;
  scrollData: [];
  pullup: boolean;
  pulldown: boolean;
  beforeScroll: boolean;
  refreshDelay: number;
}
// 各属性的默认值 使用了关键字withDefaults 以及defineProps
const props = withDefaults(defineProps<scrollProps>(), {
  probeType: 1,
  click: true, // 点击列表是否派发 click 事件
  scrollx: false, // 是否开启横向滚动
  listenScroll: true, // 是否派发滚动事件
  scrollData: undefined, // 列表的数据
  pullup: true, // 是否派发滚动到底部的事件，用于上拉加载
  pulldown: true, // 是否派发顶部下拉的事件，用于下拉刷新
  beforeScroll: true, // 是否派发列表滚动开始的事件
  refreshDelay: 20, // 当数据更新后，刷新 scroll 的延时
});
// eslint-disable-next-line func-call-spacing
// 将this.$emit 使用关键字 defineEmits
const emit = defineEmits<{
  (e: "scroll", value: number): void;
  (e: "scrollToEnd"): void;
  (e: "pulldown"): void;
  (e: "beforeScroll"): void;
}>();
function initScroll(){
  if (!wrapper.value) {
    return 0;
  }
  scroll.value = new BScroll(wrapper.value as HTMLDivElement, {
    probeType: props.probeType,
    click: props.click,
    scrollx: props.scrollx,
  });
  // console.log(scroll.value);
  // 是否派发滚动事件
  if (props.listenScroll) {
    scroll.value.on("scroll", (position: number) => {
      // console.log(position);
      emit("scroll", position);
    });
  }
  // 是否派发滚动到底部事件
  if (props.pullup) {
    scroll.value.on("scrollEnd", () => {
      if (scroll.value.y < scroll.value.maxScrollY) {
        emit("scrollToEnd");
      }
    });
  }
  // 下拉刷新事件
  if (props.pulldown) {
    scroll.value.on("touchEnd", (pos: any) => {
      if (pos.y > 50) {
        emit("pulldown");
      }
    });
  }
  // 列表滚动前触发
  if (props.beforeScroll) {
    scroll.value.on("beforeScrollStart", () => {
      emit("beforeScroll");
    });
  }
}
function disable() {
  scroll.value?.disable();
}
function enable() {
  scroll.value?.enable();
}
function refresh() {
  scroll.value?.refresh();
}
function scrollTo(...arg: any[]) {
  scroll.value?.scrollTo(arg);
}
function scrollToElement(...arg: any[]) {
  scroll.value?.scrollToElement(arg);
}
onMounted(() => {
  nextTick(() => {
    initScroll();
  });
});
watch(props.scrollData, () => {
  setTimeout(() => {
    refresh();
  }, props.refreshDelay);
});
</script>
  
  <style>
.scroll-wrapper {
  width: 100%;
  height: 100%;
}
</style>
  